import { IUserData } from "@/view/editor/ts/EditorModels";
import { Box3, Object3D } from "three";
import * as THREE from 'three'

export interface ICreatBox3Params {
    /**包围盒的宽高 */
    boxGeometry?: {
        width?: number,
        height?: number,
        depth?: number,
    },
    /**包围盒的位置 */
    position?: Partial<THREE.Vector3>
}

export interface IBox3ControlsOptions {
    /** 要被生成包围盒的模型 */
    mesh: Object3D,
    /** 包围盒的名字 */
    box3Name: string,
    /** 是否初始化的时候就生成默认包围盒, 如果false的情况，必须手动调用getBox3ByMesh方法 */
    isInitBox?: boolean
}
export class Box3Controls {
    static numberInstance: number = 1;
    mesh!: Object3D;
    box3Name: string;
    box3Mesh!: THREE.Mesh;
    option!: IBox3ControlsOptions
    box3!: THREE.Box3;

    constructor(option: IBox3ControlsOptions) {
        this.option = {
            isInitBox: true,
            ...option,
        }
        this.mesh = option.mesh;
        this.box3Name = option.box3Name;
        Box3Controls.numberInstance++
        this.option.isInitBox && this.getBox3ByMesh();
    }

    /** 创建包围盒，获取长宽高 */
    static getRuleBox3ByMesh(mesh: Object3D) {
        const aabb = new THREE.Box3();
        aabb.setFromObject(mesh);
        return {
            box3: aabb,
            width: aabb.max.x - aabb.min.x,
            height: aabb.max.y - aabb.min.y,
            depth: aabb.max.z - aabb.min.z
        }
    }

    /** 根据group创建一个包围盒 */
    getBox3ByMesh(params?: ICreatBox3Params) {
        let rules = Box3Controls.getRuleBox3ByMesh(this.mesh);
        this.box3 = rules.box3;
        let width = params?.boxGeometry?.width ?? rules.width;
        let height = params?.boxGeometry?.height ?? rules.height;
        let depth = params?.boxGeometry?.depth ?? rules.depth;
        let geometry: THREE.BoxGeometry = new THREE.BoxGeometry(width, height, depth);
        const material = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.3 });
        const box3Mesh = new THREE.Mesh(geometry, material);
        let aabbPostion = new THREE.Vector3();
        rules.box3.getCenter(aabbPostion)
        let position: THREE.Vector3 = ((params?.position || aabbPostion) as THREE.Vector3).clone();
        let { x, y, z } = position;
        // box3Mesh.position.set(x, y, z);
        box3Mesh.name = this.box3Name;
        box3Mesh.visible = false;
        this.mesh.add(box3Mesh);
        this.mesh.position.set(x, y, z);
        this.mesh.children[0].position.set(-x, -y, -z); // 此处必须时group嵌套group用于重新计算位置，绕中心点旋转
        this.box3Mesh = box3Mesh;
    }
}
